package com.mbigger.admin.service.impl;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.mbigger.admin.common.RequestHolder;
import com.mbigger.admin.dao.RoleAclMapper;
import com.mbigger.admin.dao.RoleMapper;
import com.mbigger.admin.dao.RoleUserMapper;
import com.mbigger.admin.dao.UserMapper;
import com.mbigger.admin.entity.Role;
import com.mbigger.admin.entity.User;
import com.mbigger.admin.exception.ParamException;
import com.mbigger.admin.param.RoleParam;
import com.mbigger.admin.service.RoleService;
import com.mbigger.admin.util.BeanValidator;
import com.mbigger.admin.util.IpUtil;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl implements RoleService{

	@Autowired
	private RoleMapper roleMapper;
	@Autowired
	private RoleUserMapper roleUserMapper;
	@Autowired
	private RoleAclMapper roleAclMapper;
	@Autowired
	private UserMapper userMapper;

	public void save(RoleParam param) {
		BeanValidator.check(param);
		if (checkExist(param.getName(), param.getId())) {
			throw new ParamException("角色名称已经存在");
		}
		Role role = Role.builder().name(param.getName()).status(param.getStatus()).type(param.getType())
				.remark(param.getRemark()).build();
		role.setOperator(RequestHolder.getCurrentUser().getUsername());
		role.setOperateIp(IpUtil.getRemoteIp(RequestHolder.getCurrentRequest()));
		role.setOperateTime(new Date());
		roleMapper.insert(role);
	}

	public void update(RoleParam param) {
		BeanValidator.check(param);
		if (checkExist(param.getName(), param.getId())) {
			throw new ParamException("角色名称已经存在");
		}
		Role before = roleMapper.selectById(param.getId());
		Preconditions.checkNotNull(before, "待更新的角色不存在");

		Role after = Role.builder().id(param.getId()).name(param.getName()).status(param.getStatus())
				.type(param.getType()).remark(param.getRemark()).build();
		after.setOperator(RequestHolder.getCurrentUser().getUsername());
		after.setOperateIp(IpUtil.getRemoteIp(RequestHolder.getCurrentRequest()));
		after.setOperateTime(new Date());
		roleMapper.updateById(after);
	}

	public List<Role> getAll() {
		return roleMapper.getAll();
	}

	private boolean checkExist(String name, Integer id) {
		return roleMapper.countByName(name, id) > 0;
	}

	public List<Role> getRoleListByUserId(int userId) {
		List<Integer> roleIdList = roleUserMapper.getRoleIdListByUserId(userId);
		if (CollectionUtils.isEmpty(roleIdList)) {
			return Lists.newArrayList();
		}
		return roleMapper.getByIdList(roleIdList);
	}

	public List<Role> getRoleListByAclId(int aclId) {
		List<Integer> roleIdList = roleAclMapper.getRoleIdListByAclId(aclId);
		if (CollectionUtils.isEmpty(roleIdList)) {
			return Lists.newArrayList();
		}
		return roleMapper.getByIdList(roleIdList);
	}

	public List<User> getUserListByRoleList(List<Role> roleList) {
		if (CollectionUtils.isEmpty(roleList)) {
			return Lists.newArrayList();
		}
		List<Integer> roleIdList = roleList.stream().map(role -> role.getId()).collect(Collectors.toList());
		List<Integer> userIdList = roleUserMapper.getUserIdListByRoleIdList(roleIdList);
		if (CollectionUtils.isEmpty(userIdList)) {
			return Lists.newArrayList();
		}
		return userMapper.getByIdList(userIdList);
	}
}
